找传奇、传世资源到传世资源站!

C# 12306订票软件 实例源码下载

8.5玩家评分(1人评分)
下载后可评
介绍 评论 失效链接反馈

C# 12306订票软件 实例源码下载 C#语言基础-第1张using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Threading;using Debug = System.Diagnostics.Debug;namespace Piao{ public partial class MainForm : Form { private delegate void UpdateFormControlDelegate(object arg); Func<Image, string> captchaHandle;//initialized in ctor. private static Mutex threadMutex = new Mutex(false, "{69082C9C-0783-41B8-BC32-BD5556F10D09}"); DateTime lastPress = DateTime.Today; string pressed = string.Empty; int WORKER_TIMEOUT_MINUTES = 60; int ORDER_DAY_AHEAD = 11; Win7ProcessIcon win7SuperIcon = new Win7ProcessIcon(); public MainForm() { InitializeComponent(); InitializeBackgroundWorker(); InitializeControlsFromSetting(); InitializeCaptchaDelegate();#if DEBUG this.Text = " - DEBUG VERSION";#endif } private void txt_userFromStation_Autocompletion(object sender, KeyPressEventArgs e) { ComboBox box = (sender as ComboBox); BindingSource filterSource = box.DataSource as BindingSource; if (filterSource == null) return; //reset all columns if (e.KeyChar == (char)Keys.Escape) { if (box.SelectedIndex > 0) { string text = box.Text; filterSource.Filter = string.Empty; box.Text = text; } else filterSource.Filter = string.Empty; e.Handled = true; return; } //only accept valid input [a-zA-Z] //65-90 97-122 bool onlyLetters = (e.KeyChar >= (char)65 && e.KeyChar <= (char)90) || (e.KeyChar >= (char)97 && e.KeyChar <= (char)122); if (!onlyLetters) return; //timeout to clear cached input TimeSpan ts = DateTime.Now - lastPress; if (ts.TotalSeconds > 1) { pressed = string.Empty; } lastPress = DateTime.Now; pressed = e.KeyChar.ToString().ToUpper(); //dont use empty data source , the combox will throw ArgumentOutofRangeException //before that there is an empty row added in the table, it will be default item when search has no result string searchQuery = string.Format("[{0}] like '{1}%'", Global.DataComlumnPinYin, pressed); if (Global.StationNameTable.Select(searchQuery).Length == 0) searchQuery = string.Format("[{0}] is null", Global.DataComlumnPinYin); Log.Debug("filter by {0}", searchQuery); filterSource.Filter = searchQuery; //only handle the first char for navigation if (pressed.Length != 1) e.Handled = true; Debug.WriteLine(pressed); } private void txt_webCaptcha_KeyPressForFilter(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Back || e.KeyChar == (char)Keys.Delete) return; if (txt_webCaptcha.Text.Length >= 4) { e.Handled = true; return; } if ((e.KeyChar < '0' && e.KeyChar > '9') || (e.KeyChar < 'a' && e.KeyChar > 'z') || (e.KeyChar < 'A' && e.KeyChar > 'Z') || (e.KeyChar == ' ') ) e.Handled = true; } /// <summary> /// read server city names. /// </summary> private void StartPrep() { Log.Debug("start:after logon init."); UpdateFormControlDelegate initialzeStationThreadDelegate = new UpdateFormControlDelegate(arg => { if (Global.StationNameDict.Count == 0) { MessageBox.Show("未能初始化,关闭并重启窗口再试。", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } try { //here assign data source only once if (txt_userFromStation.DataSource == null) { Log.Debug("apply data source to controls"); BindingSource bindSourceFrom = new BindingSource(); BindingSource bindSourceTo = new BindingSource(); //use different data source bindSourceFrom.DataSource = Global.StationNameTable; bindSourceTo.DataSource = Global.StationNameTable.Copy(); txt_userFromStation.DataSource = bindSourceFrom; txt_userFromStation.ValueMember = Global.DataComlumnDisplayText; txt_userToStation.DataSource = bindSourceTo; txt_userToStation.ValueMember = Global.DataComlumnDisplayText; } txt_userFromStation.Enabled = true; txt_userToStation.Enabled = true; txt_userFromStation.Text = Configurations.txt_userFromStation; txt_userToStation.Text = Configurations.txt_userToStation; } catch (Exception exc) { Log.Debug(exc.ToString()); } }); UpdateFormControlDelegate initialzeSeatTypesThreadDelegate = new UpdateFormControlDelegate(arg => { Log.Debug("refresh seat types."); List<JsonObject> list = arg as List<JsonObject>; if (list == null || list.Count == 0) return; try { foreach (JsonObject obj in list) { if (chk_userSeatTypes.Items.Contains(obj.value) == false) { chk_userSeatTypes.Items.Add(obj.value); } } if (chk_userSeatTypes.Items.Count > 2) { chk_userSeatTypes.SetItemChecked(0, true); chk_userSeatTypes.SetItemChecked(1, true); } Log.Debug("end:select first seat as default."); txt_userToStation_QueryStStrainAll(txt_userToStation, EventArgs.Empty); } catch (Exception exc) { Log.Debug(exc.ToString()); } }); UpdateFormControlDelegate initialzeControlDisplayThreadDelegate = new UpdateFormControlDelegate(arg => { Log.Debug("end:app init is complete."); menu_status.Text = "Ready"; this.TopMost = false; group_captcha.Enabled = true; group_login.Enabled = true; group_ticket.Enabled = true; group_webform.Enabled = true; }); Thread thPrep = new Thread(() => { int i = 0; while (i < 2) { if (Global.StationNameDict.Count == 0) UserOpration.Instance.QueryStationName(); else if (Global.TicketCodeList.Count == 0) UserOpration.Instance.QuerySeatTypes(); else break; CheckThreadStateToAbort(); Thread.Sleep(1000); } this.Invoke(initialzeStationThreadDelegate, Global.StationNameDict); this.Invoke(initialzeSeatTypesThreadDelegate, Global.TicketCodeList); this.Invoke(initialzeControlDisplayThreadDelegate, ""); }); thPrep.Start(); } private void btn_login_Click(object sender, EventArgs e) { Log.Debug("start:log in"); this.btn_login.Enabled = false; txt_webCaptcha.Focus(); string user = txt_userWebName.Text; string pwd = txt_userWebPassword.Text; UpdateFormControlDelegate loginComplete = new UpdateFormControlDelegate(arg => { string welcomename = arg as string; user_imageBox.Image = null; lbl_userCaptchaInfo.Text = string.Empty; txt_webCaptcha.Text = null; btn_login.Enabled = true; btn_login.Focus(); if (!string.IsNullOrEmpty(welcomename)) { this.Text = arg.ToString(); menu_status.Text = "登陆成功"; menu_start.ForeColor = Color.Red; menu_start.Enabled = true; StartPrep(); Log.Message("已登陆, 等待加载成功后点击 {0} 刷新; 站名首字母查询不支持多音字。", menu_start.Text); } Log.Debug("log in action is complete."); }); Thread waitInputThread = new Thread(() => { string propmtString = string.Empty; for (int i = 0; i < int.MaxValue; i ) { //retry logon for 3 times if failed propmtString = UserOpration.NewInstance().Login(captchaHandle, user, pwd); if (!string.IsNullOrEmpty(propmtString)) break; } this.Invoke(loginComplete, propmtString); }); waitInputThread.SetApartmentState(ApartmentState.STA); waitInputThread.Start(); } private void txt_userToStation_QueryStStrainAll(object sender, EventArgs e) { if (txt_userToStation.SelectedIndex < 0 || txt_userFromStation.SelectedIndex < 0 || string.IsNullOrEmpty(txt_userToStation.Text) || string.IsNullOrEmpty(txt_userFromStation.Text)) return; if (txt_dateTimePicker.Value <= DateTime.Today) { Log.Error("日期需要大于今日. "); return; } Log.Debug("start:search trains."); txt_userTrains.Items.Clear(); txt_userTrains.Enabled = false; txt_userOrderTrainName.Text = string.Empty; txt_userOrderTicketLeft.Text = string.Empty; string day = txt_dateTimePicker.Value.ToString("yyyy-MM-dd"); //first one is initial letter for index string fromText = txt_userFromStation.Text.Split(',')[1]; string toText = txt_userToStation.Text.Split(',')[1]; //already in dropdown so index won't be out of bound. string fromCode = FindCodeByChineseName(fromText); string toCode = FindCodeByChineseName(toText); if (fromCode == toCode) return; if (txt_userFromStation.SelectedIndex < 0 || txt_userToStation.SelectedIndex < 0) { txt_userTrains.Enabled = false; return; } SetWorkStatus(true); UpdateFormControlDelegate initializeTrainListThreadDelegate = new UpdateFormControlDelegate(arg => { try { Log.Debug("start:set data to controls for seat types."); Comparison<JsonObject> compareDelegate = delegate(JsonObject x, JsonObject y) { if (x.value[0] == y.value[0]) { return 0; } int result = x.value[0] > y.value[0] ? -1 : 1; return result; }; List<object> extraNames = new List<object>(); List<JsonObject> source = arg as List<JsonObject>; source.Sort(compareDelegate); foreach (JsonObject item in source) { if (item.end_station_name == toText) //put exact match to the beginning and put the rest to endtxt_userTrains.Items.Add(item.value); else extraNames.Add(item.value); } txt_userTrains.Items.AddRange(extraNames.ToArray<object>()); if (txt_userTrains.Items.Count > 0) { txt_userTrains.Enabled = true; if (txt_userTrains.Items.Contains(Configurations.txt_userTrains)) { txt_userTrains.SelectedItem = Configurations.txt_userTrains; } else txt_userTrains.SelectedIndex = 0; Log.Debug("end:retrieve train list is complete."); txt_userTrains.Focus(); } else { Log.Error("[{0}] 到 [{1}] 车次信息暂无。", fromText, toText); } } catch (Exception ex) { Log.Debug(ex.ToString()); } finally { SetWorkStatus(false); } }); Thread thPrep = new Thread(() => { if (threadMutex.WaitOne(TimeSpan.Zero)) { try { object stationData = UserOpration.Instance.QueryStStrainAll(day, fromCode, toCode); this.Invoke(initializeTrainListThreadDelegate, stationData); } finally { threadMutex.ReleaseMutex(); } } else { Log.Debug("Thread is busy, job of this thread is aborted. from {0} to {1}", fromText, toText); } }); thPrep.SetApartmentState(ApartmentState.STA); thPrep.Start(); } /// <summary> /// get train info by id. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txt_userTrains_QueryLeftTickets(object sender, EventArgs e) { if (txt_dateTimePicker.Value <= DateTime.Today) { Log.Error("日期需要大于今日. "); return; } lst_trainDetail.Items.Clear(); txt_userOrderTicketLeft.Text = ""; txt_userOrderTrainName.Text = ""; if (txt_userTrains.SelectedIndex < 0) { this.lst_trainDetail.Tag = null; return; } Log.Debug("start:query left tickets"); string trainId = txt_userTrains.SelectedItem.ToString(); var train = Global.TrainCodeList.Find(t => t.value == trainId); if (train == null) { this.lst_trainDetail.Tag = null; return; } try { SetWorkStatus(true); //query left ticket string day = txt_dateTimePicker.Value.ToString("yyyy-MM-dd"); string from = FindCodeByChineseName(txt_userFromStation.Text.Split(',')[1]); string to = FindCodeByChineseName(txt_userToStation.Text.Split(',')[1]); //set data tag OrderData odata = new OrderData() { station_train_code = train.value, train_date = day, seattype_num = "", from_station_telecode = from, to_station_telecode = to, include_student = "00", from_station_telecode_name = "始发站", to_station_telecode_name = "目的站", round_train_date = "", round_start_time_str = "00:00--24:00", single_round_type = "1", train_pass_type = "QB", train_class_arr = "QB#D#Z#T#K#QT#", start_time_str = "00:00--24:00", lishi = train.lishi, train_start_time = train.start_time, trainno = train.id, arrive_time = "15:42", from_station_name = "始发站", to_station_name = "目的站", ypInfoDetail = train.ypInfoDetail, }; txt_userOrderTrainName.Text = train.value; //station chinese name to code after output bool result = UserOpration.Instance.QueryLeftTicket(day, ref from, ref to, train.id, ref odata); txt_userOrderTicketLeft.Text = result ? "有" : "无"; Log.Debug("end: query left ticket, attach object data to tag."); //update listview with property 'lishi' var propList = train.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); foreach (var p in propList) { string val = p.GetValue(train) as string; var item = new ListViewItem(p.Name); item.SubItems.Add(val); lst_trainDetail.Items.Add(item); } this.lst_trainDetail.Tag = odata; } catch (Exception ex) { Log.Debug(ex.ToString()); } finally { SetWorkStatus(false); } } private void menu_start_Click(object sender, EventArgs e) { Log.Debug("start:timer enabled for search."); Global.SeatTypeTargets = new List<JsonObject>(); foreach (var checkeditem in chk_userSeatTypes.CheckedItems) { JsonObject obj = null; if ( (obj = Global.TicketCodeList.Find(j => j.value == checkeditem.ToString())) != null) { Global.SeatTypeTargets.Add(obj); continue; } } if (Global.SeatTypeTargets.Count == 0) { MessageBox.Show("需要选择票类型", "Error"); return; } if (lst_trainDetail.Tag == null) { MessageBox.Show("需要选择一个列车, 等待加载或选择。", "Error"); return; } SetWorkStatus(true); UserData user = new UserData(); //user.passenger_1_seat = tickets[0].id; user.passenger_1_ticket = "1"; //成人 user.passenger_1_name = txt_userSeatName.Text; user.passenger_1_cardtype = "1";//二代身份证 user.passenger_1_cardno = txt_userIdNumber.Text; user.passenger_1_mobileno = txt_userSeatTel.Text; this.backgroundWorker1.RunWorkerAsync(user); } private void menu_cancel_Click(object sender, EventArgs e) { Log.Debug("start:timer abort signal sent."); if (this.backgroundWorker1.IsBusy) { this.backgroundWorker1.CancelAsync(); } } private void menu_ShowWebPage_Click(object sender, EventArgs e) { WebForm web = new WebForm(); web.Show(); } void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { this.Invoke(new UpdateFormControlDelegate(a => { win7SuperIcon.SetState(this.Handle, TBPFLAG.TBPF_NOPROGRESS); Log.Message("##运行已经停止。##"); SetWorkStatus(false); notifyIcon1.ShowBalloonTip(3000, "12306", "运行已经停止。", ToolTipIcon.Info); }), ""); } void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; OrderData odata = lst_trainDetail.Tag as OrderData; UserData user = e.Argument as UserData; if (user == null) { return; } Log.Message("开始运行, 查询超时约{1}分钟后停止, 点击 {0} 可以立刻停止。", menu_cancel.Text, WORKER_TIMEOUT_MINUTES); System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); bool result = false; while (watch.Elapsed.TotalMinutes < WORKER_TIMEOUT_MINUTES) { if ((worker.CancellationPending == true)) { e.Cancel = true; break; } else { result = UserOpration.Instance.QueryLeftTicket(odata.train_date, ref odata.from_station_telecode, ref odata.to_station_telecode, odata.trainno, ref odata); if (result) break; Thread.Sleep(1000); } int percent = (int)(100 * watch.Elapsed.TotalMinutes / WORKER_TIMEOUT_MINUTES); percent = percent < 30 ? 30 : percent; //for virsual effort set to 30% worker.ReportProgress(percent); } if (result == false) { Log.Error("车次信息不可用, 停止提交。 "); return; } UserOpration.Instance.SubmitOrderRequest(odata, user, captchaHandle); } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { win7SuperIcon.SetState(this.Handle, TBPFLAG.TBPF_NORMAL); win7SuperIcon.SetProgress(this.Handle, (ulong)e.ProgressPercentage, 100); } protected override void OnClosing(CancelEventArgs e) { menu_cancel_Click(menu_cancel, null); if (txt_userFromStation.Text != null) Configurations.txt_userFromStation = txt_userFromStation.Text.ToString(); if (txt_userToStation.Text != null) Configurations.txt_userToStation = txt_userToStation.Text.ToString(); if (txt_userTrains.Text != null) Configurations.txt_userTrains = txt_userTrains.Text.ToString(); Properties.Settings.Default.Save(); Configurations.Save(); base.OnClosing(e); } #region private func private void SetWorkStatus(bool isworking = true) { menu_status.Text = isworking ? "正在查询" : "Ready"; menu_start.Enabled = !isworking; group_login.Enabled = !isworking; group_webform.Enabled = !isworking; menu_cancel.Enabled = isworking; } private void InitializeControlsFromSetting() { string procName = System.Diagnostics.Process.GetCurrentProcess().ProcessName; int pCount = System.Diagnostics.Process.GetProcessesByName(procName).Length - 1; this.StartPosition = FormStartPosition.Manual; this.Location = new Point( Screen.PrimaryScreen.WorkingArea.Width - Width - 400 * pCount, 100 * pCount); this.Icon = Icon.ExtractAssociatedIcon(Environment.ExpandEnvironmentVariables("%windir%" @"\system32\winver.exe")); this.notifyIcon1.Icon = this.Icon; txt_dateTimePicker.Value = DateTime.Today.Add(new TimeSpan(ORDER_DAY_AHEAD, 0, 0, 0)); chk_userSeatTypes.Items.AddRange(Configurations.chk_userSeatTypes.Split(',')); Log.Add(new FormLog(this.txt_log)); foreach (string p in Properties.Settings.Default.webProxy) { ToolStripMenuItem menuItem = new ToolStripMenuItem(p); menuItem.Click = (object sender, EventArgs e) => { foreach (ToolStripMenuItem i in Proxy_toolStripMenuItem.DropDownItems) { i.CheckState = CheckState.Unchecked; } ToolStripMenuItem item = sender as ToolStripMenuItem; item.CheckState = CheckState.Checked; UserOpration.Instance.ProxyName = item.Text; }; Proxy_toolStripMenuItem.DropDownItems.Add(menuItem); } KeyPressEventHandler submitHandler = delegate(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Enter) { btn_login_Click(btn_login, EventArgs.Empty); e.Handled = true; } }; txt_userWebName.KeyPress = submitHandler; txt_userWebPassword.KeyPress = submitHandler; } private void InitializeCaptchaDelegate() { UpdateFormControlDelegate updateImage = new UpdateFormControlDelegate(arg => { if (!cb_autoCaptcha.Checked) { this.BringToFront(); this.Activate(); txt_webCaptcha.Focus(); } user_imageBox.Image = arg as Image; lbl_userCaptchaInfo.Text = "60秒内输入验证码, 不区分大小写。"; }); UpdateFormControlDelegate clearCaptchaCode = new UpdateFormControlDelegate(arg => { this.TopMost = false; txt_webCaptcha.Text = string.Empty; user_imageBox.Image = null; lbl_userCaptchaInfo.Text = string.Empty; }); UpdateFormControlDelegate updateAutoCaptcha = new UpdateFormControlDelegate(arg => { txt_webCaptcha.Text = arg as string; }); captchaHandle = (img) => { if (img == null) { Log.Error("出现错误, 不能获取验证码。 "); return string.Empty; } ImageUtil.GrayImage(ref img); this.Invoke(updateImage, img); if (cb_autoCaptcha.Checked) { tessnet2.Tesseract tessocr = new tessnet2.Tesseract(); tessocr.SetVariable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); tessocr.Init(null, "eng", false); // To use correct tessdata List<tessnet2.Word> result = tessocr.DoOCR(new Bitmap(img), Rectangle.Empty); string _result = result[0].Text.Trim(); if(_result.Length<4) { _result = "1234"; } this.Invoke(updateAutoCaptcha, _result); //txt_webCaptcha.Text = result[0].Text.Trim(); Log.Error("验证码为:" result[0].Text.Trim() "置信度为:" result[0].Confidence); } else { Log.Error("!!!!!!!!! 输入验证码 !!!!!!!!!!!"); } int i = 0; while (i < 20) { Thread.Sleep(2000); if (txt_webCaptcha.Text.Length >= 4) break; CheckThreadStateToAbort(); } string ret = txt_webCaptcha.Text; this.Invoke(clearCaptchaCode, ""); return ret; }; } private void InitializeBackgroundWorker() { this.backgroundWorker1.WorkerSupportsCancellation = true; this.backgroundWorker1.DoWork = new DoWorkEventHandler(backgroundWorker1_DoWork); this.backgroundWorker1.RunWorkerCompleted = new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted); } private void CheckThreadStateToAbort() { if (this.IsDisposed || Thread.CurrentThread.ThreadState == ThreadState.AbortRequested) Thread.CurrentThread.Abort(); } private string FindCodeByChineseName(string name) { var rows = Global.StationNameTable.Select(string.Format("{0}='{1}'", Global.DataComlumnChineseName, name)); string code = rows[0][Global.DataComlumnCodeName] as string; return code; } #endregion }}

评论

发表评论必须先登陆, 您可以 登陆 或者 注册新账号 !


在线咨询: 问题反馈
客服QQ:174666394

有问题请留言,看到后及时答复